VSB-TUO/Fix post login non-interactive UI#1317
Merged
Merged
Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
added 2 commits
June 19, 2026 11:00
jr-rk
added a commit
that referenced
this pull request
Jun 20, 2026
Propagates VSB-TUO's fix #1317 to this instance. The overlay was removed when ApplicationRef.isStable settled, but isStable can be delayed for seconds by post-login admin zone activity (auth work, background polling, third-party scripts) - during which the live app stays hidden under the SSR mask and the page renders but is non-interactive (dataquest-dev/dspace-customers#725). Switch removal to the same condition root.component.html uses to show real content: !isAuthenticationBlocking && !isThemeLoading. Drop the now-unused ApplicationRef injection and the 50ms pad; keep the 15s hard fallback as a catastrophic safety net. Tests and the theme-service mock updated to match. Ref: #1317 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
jr-rk
added a commit
that referenced
this pull request
Jun 20, 2026
Propagates VSB-TUO's fix #1317 to this instance. The overlay was removed when ApplicationRef.isStable settled, but isStable can be delayed for seconds by post-login admin zone activity (auth work, background polling, third-party scripts) - during which the live app stays hidden under the SSR mask and the page renders but is non-interactive (dataquest-dev/dspace-customers#725). Switch removal to the same condition root.component.html uses to show real content: !isAuthenticationBlocking && !isThemeLoading. Drop the now-unused ApplicationRef injection and the 50ms pad; keep the 15s hard fallback as a catastrophic safety net. Tests and the theme-service mock updated to match. Ref: #1317 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
jr-rk
added a commit
that referenced
this pull request
Jun 20, 2026
Propagates VSB-TUO's fix #1317 to this instance. The overlay was removed when ApplicationRef.isStable settled, but isStable can be delayed for seconds by post-login admin zone activity (auth work, background polling, third-party scripts) - during which the live app stays hidden under the SSR mask and the page renders but is non-interactive (dataquest-dev/dspace-customers#725). Switch removal to the same condition root.component.html uses to show real content: !isAuthenticationBlocking && !isThemeLoading. Drop the now-unused ApplicationRef injection and the 50ms pad; keep the 15s hard fallback as a catastrophic safety net. Tests and the theme-service mock updated to match. Ref: #1317 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
jr-rk
added a commit
that referenced
this pull request
Jun 20, 2026
Propagates VSB-TUO's fix #1317 to this instance. The overlay was removed when ApplicationRef.isStable settled, but isStable can be delayed for seconds by post-login admin zone activity (auth work, background polling, third-party scripts) - during which the live app stays hidden under the SSR mask and the page renders but is non-interactive (dataquest-dev/dspace-customers#725). Switch removal to the same condition root.component.html uses to show real content: !isAuthenticationBlocking && !isThemeLoading. Drop the now-unused ApplicationRef injection and the 50ms pad; keep the 15s hard fallback as a catastrophic safety net. Tests and the theme-service mock updated to match. Ref: #1317 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This was referenced Jun 20, 2026
milanmajchrak
added a commit
that referenced
this pull request
Jun 22, 2026
… on isStable or bare auth gate) The SSR anti-flicker overlay (PR #1288) is removed by AppComponent. Two prior approaches each fixed one symptom and reintroduced the other: - #1288 waited for ApplicationRef.isStable: no flicker, but admin sessions keep the zone busy (authz/widgets, polling, AAI scripts) so isStable fires many seconds late (or hits the 15s fallback), leaving the live, already-rendered page masked & non-interactive (dspace-customers#725). - #1317 switched to the loader-swap gate (!isAuthenticationBlocking && !isThemeLoading) + a single requestAnimationFrame: fast/interactive, but the gate only un-hides <router-outlet> and one rAF runs before paint, so the snapshot is dropped over an empty <ds-app> -> the flicker returned. Neither signal means "the routed content is painted AND the app is interactive": isStable over-waits (couples removal to unrelated background async); the auth/theme gate under-waits (decoupled from actual content paint). This keeps #1317's decoupling from isStable but, after the gate opens, waits across animation frames until the real <ds-app> is actually laid out (height >= 200px AND its #main-content host present) before removing the overlay, capped at ~3s (MAX_FRAMES) so background async can never hold it open. The 15s fallback in index.html stays as the catastrophic-error net. Verified (DSpace 7.6.5 backend, CPU 4x, hard reload, admin session): - #1288: TTI 15963ms (page masked ~13s) #1317: ds-app height 0 at removal (217ms flash) - fix: TTI ~3.1-3.4s, ds-app height 5281px at removal, gap <= 0 (no flash), 3x deterministic; anon reload also no-flicker; 0 CORS and 0 SSR/hydration/NG0 console errors. Verification videos are linked in the PR description. Refs: dspace-customers#725, PR #1288, PR #1317 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
milanmajchrak
added a commit
that referenced
this pull request
Jun 22, 2026
… on isStable or bare auth gate) (#1318) The SSR anti-flicker overlay (PR #1288) is removed by AppComponent. Two prior approaches each fixed one symptom and reintroduced the other: - #1288 waited for ApplicationRef.isStable: no flicker, but admin sessions keep the zone busy (authz/widgets, polling, AAI scripts) so isStable fires many seconds late (or hits the 15s fallback), leaving the live, already-rendered page masked & non-interactive (dspace-customers#725). - #1317 switched to the loader-swap gate (!isAuthenticationBlocking && !isThemeLoading) + a single requestAnimationFrame: fast/interactive, but the gate only un-hides <router-outlet> and one rAF runs before paint, so the snapshot is dropped over an empty <ds-app> -> the flicker returned. Neither signal means "the routed content is painted AND the app is interactive": isStable over-waits (couples removal to unrelated background async); the auth/theme gate under-waits (decoupled from actual content paint). This keeps #1317's decoupling from isStable but, after the gate opens, waits across animation frames until the real <ds-app> is actually laid out (height >= 200px AND its #main-content host present) before removing the overlay, capped at ~3s (MAX_FRAMES) so background async can never hold it open. The 15s fallback in index.html stays as the catastrophic-error net. Verified (DSpace 7.6.5 backend, CPU 4x, hard reload, admin session): - #1288: TTI 15963ms (page masked ~13s) #1317: ds-app height 0 at removal (217ms flash) - fix: TTI ~3.1-3.4s, ds-app height 5281px at removal, gap <= 0 (no flash), 3x deterministic; anon reload also no-flicker; 0 CORS and 0 SSR/hydration/NG0 console errors. Verification videos are linked in the PR description. Refs: dspace-customers#725, PR #1288, PR #1317 Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
milanmajchrak
added a commit
that referenced
this pull request
Jun 23, 2026
…er WebDriver (close #725) Addresses an expert review of the DOM-settle change: DOM-settle alone shortened but did not eliminate issue #725, because the masking window still left the page non-interactive (the opaque overlay sat over a visibility:hidden <ds-app>, so clicks landed on nothing) and still produced duplicate DOM that breaks strict-mode E2E locators. Changes: - index.html: drop the `ds-app[data-dspace-ssr-hidden]{visibility:hidden}` rule and give the overlay min-height:100vh. The overlay is already opaque + pointer-events:none, so it still masks the CSR rebuild visually, but clicks now pass THROUGH it to the real, still-visible <ds-app> underneath. The page is therefore interactive the entire time it is masked -> #725 ("looks rendered but nothing is clickable") cannot recur, even if removal rides the 10s cap. The snapshot is marked aria-hidden so AT (and the duplicate-node concern) target the live app, not the snapshot. - index.html: also bypass the overlay for WebDriver runners (navigator.webdriver), mirroring the existing Cypress guard, so Playwright/Selenium see no overlay and no duplicate DOM (fixes the #725 strict-mode locator failure). - app.component.ts: exclude the admin-sidebar subtree from the DOM-settle MutationObserver (its long :enter/:leave animations would keep re-arming the quiet window and push admin logins toward the cap); add OnDestroy + takeUntil + observer/timer teardown. - Fix stale `ApplicationRef.isStable` / `removeSsrOverlayWhenStable` comments (index.html, typings.d.ts). Verified against the live build (Playwright, CPU/network throttled): - WebDriver run: overlay absent (no duplicate DOM). - webdriver spoofed false (real-user path): a navbar click WHILE the snapshot is still shown reaches the live <ds-app> (interactive under mask). - anon reveal settled, CLS after reveal = 0; admin reveal settled (reason "settled", not cap), CLS after reveal = 0. Refs: dspace-customers#725, PR #1288, PR #1317, PR #1318, PR #1321 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
milanmajchrak
added a commit
that referenced
this pull request
Jun 23, 2026
…moved only after the routed DOM settles (#1321) * fix(ssr-overlay): remove overlay only after the routed page DOM settles (real home-page flicker) Follow-up to #1318. On a real instance (VSB / dev-6.pc), an incognito Ctrl+Shift+R still flickered: the deployed code dropped the SSR snapshot ~3.2s in, while the home page was only half-rendered (search box, community list and several navbar items not yet present, content showing "Recent Submissions") and then everything popped into place ~600ms later. Captured frame-by-frame against the live instance. Root cause: the home page renders piecewise (each section fetches its own data), so the previous "<ds-app> has #main-content and height>=200" heuristic was satisfied while the page was still building -> snapshot removed too early -> visible flicker. Fix: after the auth/theme gate opens, keep the snapshot until the real <ds-app> subtree has SETTLED -- no element added/removed for SETTLE_QUIET_MS (600ms) -- via a MutationObserver, requiring minimum content first and capped at SETTLE_MAX_MS (10s). This stays decoupled from ApplicationRef.isStable (DOM-settle ignores non-rendering background async), so it does not bring back the post-login non-interactive page (#725): admin reveals in ~5s, not ~15s. Validated against the live dev-6.pc instance by intercepting the overlay-removal and driving it with this condition: - anon reload : drops @ ~4.8s, page COMPLETE (search + community list + full navbar) - admin reload: drops @ ~5.0s (reason "settled", not the cap), page complete vs the deployed code dropping @ ~3.2-3.6s on a half-built page. Refs: dspace-customers#725, PR #1288, PR #1317, PR #1318 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(ssr-overlay): make the masked page interactive + skip overlay under WebDriver (close #725) Addresses an expert review of the DOM-settle change: DOM-settle alone shortened but did not eliminate issue #725, because the masking window still left the page non-interactive (the opaque overlay sat over a visibility:hidden <ds-app>, so clicks landed on nothing) and still produced duplicate DOM that breaks strict-mode E2E locators. Changes: - index.html: drop the `ds-app[data-dspace-ssr-hidden]{visibility:hidden}` rule and give the overlay min-height:100vh. The overlay is already opaque + pointer-events:none, so it still masks the CSR rebuild visually, but clicks now pass THROUGH it to the real, still-visible <ds-app> underneath. The page is therefore interactive the entire time it is masked -> #725 ("looks rendered but nothing is clickable") cannot recur, even if removal rides the 10s cap. The snapshot is marked aria-hidden so AT (and the duplicate-node concern) target the live app, not the snapshot. - index.html: also bypass the overlay for WebDriver runners (navigator.webdriver), mirroring the existing Cypress guard, so Playwright/Selenium see no overlay and no duplicate DOM (fixes the #725 strict-mode locator failure). - app.component.ts: exclude the admin-sidebar subtree from the DOM-settle MutationObserver (its long :enter/:leave animations would keep re-arming the quiet window and push admin logins toward the cap); add OnDestroy + takeUntil + observer/timer teardown. - Fix stale `ApplicationRef.isStable` / `removeSsrOverlayWhenStable` comments (index.html, typings.d.ts). Verified against the live build (Playwright, CPU/network throttled): - WebDriver run: overlay absent (no duplicate DOM). - webdriver spoofed false (real-user path): a navbar click WHILE the snapshot is still shown reaches the live <ds-app> (interactive under mask). - anon reveal settled, CLS after reveal = 0; admin reveal settled (reason "settled", not cap), CLS after reveal = 0. Refs: dspace-customers#725, PR #1288, PR #1317, PR #1318, PR #1321 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * refactor(ssr-overlay): declarative DOM-settle, drop fragile admin-sidebar hack (no behaviour change) The overlay-removal logic was a hard-to-read imperative blob (mutable done/quietTimer/capTimer flags, manual arm/re-arm, manual MutationObserver/teardown bookkeeping) plus a brittle string-selector hack (`inAdminSidebar` -> `closest('ds-themed-admin-sidebar, ds-admin-sidebar')`). Rewritten as small, named, single-responsibility pieces: - removeSsrOverlayWhenContentVisible(): guard + runOutsideAngular + subscribe(takeUntil(destroyed$)). - routedPageReadyToReveal$(): loader gate (take 1) -> switchMap(dsAppDomSettled$). - dsAppDomSettled$(): MutationObserver wrapped as an Observable; settle = startWith + debounceTime (the quiet window) + filter(real content); race() with timer() for the cap; take(1). - dsAppHasRenderedContent(), isElementChildListChange(), runAfterNextFrame(): tiny pure helpers. RxJS now owns debounce, the cap, and teardown (the Observable disconnects the observer on unsubscribe, takeUntil(destroyed$) ends everything on destroy), so the mutable flags, manual timers and the separate cancelOverlaySettle field are gone (net -45 lines). Dropped the admin-sidebar exclusion entirely: it was a fragile, theme-coupled selector guarding a problem that interactive-under-mask already makes harmless (riding the cap is fine when the page is clickable throughout) and that does not occur in practice (admin still settles via "settled", not the cap). Tuning constants moved to named readonly fields. Behaviour re-verified on the live build (Playwright, throttled): interactive-under-mask still works; anon + admin both reveal with reason "settled" (not cap) and CLS after reveal = 0. Refs: dspace-customers#725, PR #1321 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
jr-rk
added a commit
that referenced
this pull request
Jun 30, 2026
Supersedes the #1317 content-visible trigger backported earlier. That gate (!isAuthenticationBlocking && !isThemeLoading) still revealed a half-built page on hard reload, so VSB-TUO's #1318/#1321 keep the snapshot until the routed <ds-app> DOM has SETTLED (MutationObserver + quiet window, with a content height / #main-content check and a 10s cap). The overlay is now a purely visual mask, so the live app stays interactive underneath while it rebuilds (closes dspace-customers#725 - "looks rendered but not clickable"). index.html, app.component.ts, spec and typings are synced to VSB-TUO's final version; the VSB-only ngAfterViewInit delay(0) is omitted (these instances don't carry it). Ref: #1318, #1321 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
jr-rk
added a commit
that referenced
this pull request
Jun 30, 2026
Supersedes the #1317 content-visible trigger backported earlier. That gate (!isAuthenticationBlocking && !isThemeLoading) still revealed a half-built page on hard reload, so VSB-TUO's #1318/#1321 keep the snapshot until the routed <ds-app> DOM has SETTLED (MutationObserver + quiet window, with a content height / #main-content check and a 10s cap). The overlay is now a purely visual mask, so the live app stays interactive underneath while it rebuilds (closes dspace-customers#725 - "looks rendered but not clickable"). index.html, app.component.ts, spec and typings are synced to VSB-TUO's final version; the VSB-only ngAfterViewInit delay(0) is omitted (these instances don't carry it). Ref: #1318, #1321 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
jr-rk
added a commit
that referenced
this pull request
Jun 30, 2026
Supersedes the #1317 content-visible trigger backported earlier. That gate (!isAuthenticationBlocking && !isThemeLoading) still revealed a half-built page on hard reload, so VSB-TUO's #1318/#1321 keep the snapshot until the routed <ds-app> DOM has SETTLED (MutationObserver + quiet window, with a content height / #main-content check and a 10s cap). The overlay is now a purely visual mask, so the live app stays interactive underneath while it rebuilds (closes dspace-customers#725 - "looks rendered but not clickable"). index.html, app.component.ts, spec and typings are synced to VSB-TUO's final version; the VSB-only ngAfterViewInit delay(0) is omitted (these instances don't carry it). Ref: #1318, #1321 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
jr-rk
added a commit
that referenced
this pull request
Jun 30, 2026
Supersedes the #1317 content-visible trigger backported earlier. That gate (!isAuthenticationBlocking && !isThemeLoading) still revealed a half-built page on hard reload, so VSB-TUO's #1318/#1321 keep the snapshot until the routed <ds-app> DOM has SETTLED (MutationObserver + quiet window, with a content height / #main-content check and a 10s cap). The overlay is now a purely visual mask, so the live app stays interactive underneath while it rebuilds (closes dspace-customers#725 - "looks rendered but not clickable"). index.html, app.component.ts, spec and typings are synced to VSB-TUO's final version; the VSB-only ngAfterViewInit delay(0) is omitted (these instances don't carry it). Ref: #1318, #1321 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
milanmajchrak
pushed a commit
that referenced
this pull request
Jul 2, 2026
* Backport of Fix home-page SSR->CSR flicker * Fix: always unhide app when removing SSR anti-flicker overlay The overlay remover bailed out via `if (!el) return;` before unhiding <ds-app>, so if the overlay node went missing (browser extension, race, external script) the app stayed visibility:hidden forever -> blank page, plus the kept SSR styles leaked. Unhide the app and clean up the kept styles unconditionally, before checking for the overlay node. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Chore: drop accidentally committed build/spec logs _build.log and _spec.log are local deploy-tooling output that should never have been tracked. Remove them and gitignore /_*.log. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Test: isolate isStable override and cover the no-rAF overlay path Make the ApplicationRef.isStable override in the removeSsrOverlayWhenStable suite configurable and restore the original descriptor in afterEach, so the patched observable can't leak onto the shared TestBed instance. Add a test for the requestAnimationFrame-absent fallback branch of the remover. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Refactor: align eager-themes.module.ts with the other backport instances Bind the custom eager theme to the CustomEagerThemeModule alias used by the other customer backports so this file is byte-identical across instances. The same ./custom/eager-theme.module is still imported eagerly - no runtime, build, or bundle-size change; the custom theme stays eager (which also keeps the untyped-item theming working, ref DSpace#1897). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Build: raise initial bundle budget to 5.5mb/6mb to match the other backports Aligns ZCU-PUB's initial budget with the value the root fix (#1287) and the other customer backports use, so the budget block is identical across instances. The custom theme is already eager here, so this only widens the headroom; the build already passes under the previous 5mb error ceiling. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Refactor: remove SSR overlay on content-visible instead of isStable Propagates VSB-TUO's fix #1317 to this instance. The overlay was removed when ApplicationRef.isStable settled, but isStable can be delayed for seconds by post-login admin zone activity (auth work, background polling, third-party scripts) - during which the live app stays hidden under the SSR mask and the page renders but is non-interactive (dataquest-dev/dspace-customers#725). Switch removal to the same condition root.component.html uses to show real content: !isAuthenticationBlocking && !isThemeLoading. Drop the now-unused ApplicationRef injection and the 50ms pad; keep the 15s hard fallback as a catastrophic safety net. Tests and the theme-service mock updated to match. Ref: #1317 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Backport final SSR-overlay mechanism from VSB-TUO (#1318, #1321) Supersedes the #1317 content-visible trigger backported earlier. That gate (!isAuthenticationBlocking && !isThemeLoading) still revealed a half-built page on hard reload, so VSB-TUO's #1318/#1321 keep the snapshot until the routed <ds-app> DOM has SETTLED (MutationObserver + quiet window, with a content height / #main-content check and a 10s cap). The overlay is now a purely visual mask, so the live app stays interactive underneath while it rebuilds (closes dspace-customers#725 - "looks rendered but not clickable"). index.html, app.component.ts, spec and typings are synced to VSB-TUO's final version; the VSB-only ngAfterViewInit delay(0) is omitted (these instances don't carry it). Ref: #1318, #1321 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
milanmajchrak
pushed a commit
that referenced
this pull request
Jul 2, 2026
* Backport of Fix home-page SSR->CSR flicker * Fix: always unhide app when removing SSR anti-flicker overlay The overlay remover bailed out via `if (!el) return;` before unhiding <ds-app>, so if the overlay node went missing (browser extension, race, external script) the app stayed visibility:hidden forever -> blank page, plus the kept SSR styles leaked. Unhide the app and clean up the kept styles unconditionally, before checking for the overlay node. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Chore: drop accidentally committed build/spec logs _build.log and _spec.log are local deploy-tooling output that should never have been tracked. Remove them and gitignore /_*.log. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Test: isolate isStable override and cover the no-rAF overlay path Make the ApplicationRef.isStable override in the removeSsrOverlayWhenStable suite configurable and restore the original descriptor in afterEach, so the patched observable can't leak onto the shared TestBed instance. Add a test for the requestAnimationFrame-absent fallback branch of the remover. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Refactor: remove SSR overlay on content-visible instead of isStable Propagates VSB-TUO's fix #1317 to this instance. The overlay was removed when ApplicationRef.isStable settled, but isStable can be delayed for seconds by post-login admin zone activity (auth work, background polling, third-party scripts) - during which the live app stays hidden under the SSR mask and the page renders but is non-interactive (dataquest-dev/dspace-customers#725). Switch removal to the same condition root.component.html uses to show real content: !isAuthenticationBlocking && !isThemeLoading. Drop the now-unused ApplicationRef injection and the 50ms pad; keep the 15s hard fallback as a catastrophic safety net. Tests and the theme-service mock updated to match. Ref: #1317 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Backport final SSR-overlay mechanism from VSB-TUO (#1318, #1321) Supersedes the #1317 content-visible trigger backported earlier. That gate (!isAuthenticationBlocking && !isThemeLoading) still revealed a half-built page on hard reload, so VSB-TUO's #1318/#1321 keep the snapshot until the routed <ds-app> DOM has SETTLED (MutationObserver + quiet window, with a content height / #main-content check and a 10s cap). The overlay is now a purely visual mask, so the live app stays interactive underneath while it rebuilds (closes dspace-customers#725 - "looks rendered but not clickable"). index.html, app.component.ts, spec and typings are synced to VSB-TUO's final version; the VSB-only ngAfterViewInit delay(0) is omitted (these instances don't carry it). Ref: #1318, #1321 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
milanmajchrak
pushed a commit
that referenced
this pull request
Jul 2, 2026
* Backport of Fix home-page SSR->CSR flicker * Fix: always unhide app when removing SSR anti-flicker overlay The overlay remover bailed out via `if (!el) return;` before unhiding <ds-app>, so if the overlay node went missing (browser extension, race, external script) the app stayed visibility:hidden forever -> blank page, plus the kept SSR styles leaked. Unhide the app and clean up the kept styles unconditionally, before checking for the overlay node. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Chore: drop accidentally committed build/install/spec logs _build.log, _install.log and _spec.log are local deploy-tooling output that should never have been tracked. Remove them and gitignore /_*.log. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Test: isolate isStable override and cover the no-rAF overlay path Make the ApplicationRef.isStable override in the removeSsrOverlayWhenStable suite configurable and restore the original descriptor in afterEach, so the patched observable can't leak onto the shared TestBed instance. Add a test for the requestAnimationFrame-absent fallback branch of the remover. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Refactor: remove SSR overlay on content-visible instead of isStable Propagates VSB-TUO's fix #1317 to this instance. The overlay was removed when ApplicationRef.isStable settled, but isStable can be delayed for seconds by post-login admin zone activity (auth work, background polling, third-party scripts) - during which the live app stays hidden under the SSR mask and the page renders but is non-interactive (dataquest-dev/dspace-customers#725). Switch removal to the same condition root.component.html uses to show real content: !isAuthenticationBlocking && !isThemeLoading. Drop the now-unused ApplicationRef injection and the 50ms pad; keep the 15s hard fallback as a catastrophic safety net. Tests and the theme-service mock updated to match. Ref: #1317 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Backport final SSR-overlay mechanism from VSB-TUO (#1318, #1321) Supersedes the #1317 content-visible trigger backported earlier. That gate (!isAuthenticationBlocking && !isThemeLoading) still revealed a half-built page on hard reload, so VSB-TUO's #1318/#1321 keep the snapshot until the routed <ds-app> DOM has SETTLED (MutationObserver + quiet window, with a content height / #main-content check and a 10s cap). The overlay is now a purely visual mask, so the live app stays interactive underneath while it rebuilds (closes dspace-customers#725 - "looks rendered but not clickable"). index.html, app.component.ts, spec and typings are synced to VSB-TUO's final version; the VSB-only ngAfterViewInit delay(0) is omitted (these instances don't carry it). Ref: #1318, #1321 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
milanmajchrak
pushed a commit
that referenced
this pull request
Jul 2, 2026
* AI backport of Fix home-page SSR->CSR flicker * Fix: always unhide app when removing SSR anti-flicker overlay The overlay remover bailed out via `if (!el) return;` before unhiding <ds-app>, so if the overlay node went missing (browser extension, race, external script) the app stayed visibility:hidden forever -> blank page, plus the kept SSR styles leaked. Unhide the app and clean up the kept styles unconditionally, before checking for the overlay node. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Test: isolate isStable override and cover the no-rAF overlay path Make the ApplicationRef.isStable override in the removeSsrOverlayWhenStable suite configurable and restore the original descriptor in afterEach, so the patched observable can't leak onto the shared TestBed instance. Add a test for the requestAnimationFrame-absent fallback branch of the remover. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Refactor: remove SSR overlay on content-visible instead of isStable Propagates VSB-TUO's fix #1317 to this instance. The overlay was removed when ApplicationRef.isStable settled, but isStable can be delayed for seconds by post-login admin zone activity (auth work, background polling, third-party scripts) - during which the live app stays hidden under the SSR mask and the page renders but is non-interactive (dataquest-dev/dspace-customers#725). Switch removal to the same condition root.component.html uses to show real content: !isAuthenticationBlocking && !isThemeLoading. Drop the now-unused ApplicationRef injection and the 50ms pad; keep the 15s hard fallback as a catastrophic safety net. Tests and the theme-service mock updated to match. Ref: #1317 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Backport final SSR-overlay mechanism from VSB-TUO (#1318, #1321) Supersedes the #1317 content-visible trigger backported earlier. That gate (!isAuthenticationBlocking && !isThemeLoading) still revealed a half-built page on hard reload, so VSB-TUO's #1318/#1321 keep the snapshot until the routed <ds-app> DOM has SETTLED (MutationObserver + quiet window, with a content height / #main-content check and a 10s cap). The overlay is now a purely visual mask, so the live app stays interactive underneath while it rebuilds (closes dspace-customers#725 - "looks rendered but not clickable"). index.html, app.component.ts, spec and typings are synced to VSB-TUO's final version; the VSB-only ngAfterViewInit delay(0) is omitted (these instances don't carry it). Ref: #1318, #1321 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem description
Issue: https://github.com/dataquest-dev/dspace-customers/issues/725
Problem
On VSB, after logging in (especially as admin), the page looks rendered but remains non-interactive for several seconds.
Root Cause
The SSR anti-flicker overlay introduced in #1288 is removed based on Angular stability (ApplicationRef.isStable).
In admin sessions, post-login startup triggers more async/zone activity (auth/authorization work, admin widgets, customer scripts), which delays isStable.
During that delay, the live app stays hidden under the SSR mask, so users see UI but cannot click.
Solution
Switch overlay removal to an event-driven condition tied to actual UI readiness:
Sync verification
If en.json5 or cs.json5 translation files were updated:
yarn run sync-i18n -t src/assets/i18n/cs.json5 -ito synchronize messages, and changes are included in this PR.Manual Testing (if applicable)
Copilot review